package com.kaili.db.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.kaili.client.service.Impl.LoginUserInfoService;
import com.kaili.common.OperationType;
import com.kaili.common.exception.BaseExcept;
import com.kaili.common.stock.StockPdaInfoBean;
import com.kaili.common.util.LoginDetailUtils;
import com.kaili.common.util.SnowflakeIdFactory;
import com.kaili.db.mapper.HsEwbsDispatchMapper;
import com.kaili.db.service.*;
import com.kaili.except.ResponseStatus;
import com.kaili.pojo.dto.dispatch.DispatchAddDTO;
import com.kaili.pojo.entity.*;
import com.kaili.pojo.vo.DispatchRouteVO;
import com.kaili.pojo.vo.DispatchVO;
import com.kaili.pojo.vo.EwbDispatchVO;
import com.kaili.utils.DateUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.kaili.except.ResponseStatus.DISPATCH_STOCK_NOT_ENOUGH_ERR;
import static com.kaili.except.ResponseStatus.NOT_ENOUGH_STOCK;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author cgm
 * @since 2018-05-08
 */
@Service
@Transactional
public class HsEwbsDispatchServiceImpl extends ServiceImpl<HsEwbsDispatchMapper, HsEwbsDispatch> implements
        IHsEwbsDispatchService {

    @Autowired
    private LoginUserInfoService login;
    @Autowired
    private IHsEwbsDispatchDetailService dispatchDetailService;
    @Autowired
    private IHsOptQueryService queryService;
    @Autowired
    private IHsEwbSubStockService stockService;
    @Autowired
    private IHsEwbsDispatcherSubService ewbsDispatcherSubService;
    @Autowired
    private IHsEwbSubService hsEwbSubService;
    @Autowired
    private IHsEwbsDispatchService dispatchService;


    @Override
    public List<EwbDispatchVO> queryUndispatchEwbList(Map search) throws BaseExcept {

        return baseMapper.queryUndispatchEwbList(search);
    }

    /**
     * 查询派件信息
     *
     * @param page
     * @param search
     * @return
     * @throws BaseExcept
     */
    @Override
    public Page<DispatchVO> queryDispatchEwbList(Page<DispatchVO> page, Map search) throws BaseExcept {
        Page<DispatchVO> resultPage = page.setRecords(baseMapper.queryDispatchEwbList(page, search));
        List<DispatchVO> records = resultPage.getRecords();
        for (DispatchVO dispatchVO : records){
            Map<String,Object> map=new HashMap<>();
            map.put("operationId",dispatchVO.getOperationId());
            List<EwbDispatchVO> dispatchVOS = dispatchService.getEwbInfoByDispatchNo(map);
            dispatchVO.setEwbDispatchVOList(dispatchVOS);
        }
        return resultPage;
    }

    /**
     * 根据送货单号获取运单详情
     *
     * @param search
     * @return
     * @throws BaseExcept
     */
    @Override
    public List<EwbDispatchVO> getEwbInfoByDispatchNo(Map<String, Object> search) throws BaseExcept {

        List<EwbDispatchVO> ewbDispatchVOS = baseMapper.getEwbInfoByDispatchNo(search);
        for (EwbDispatchVO ewbDispatchVO : ewbDispatchVOS){
            Map<String,Object> map=new HashMap<>();
            map.put("ewb_no",ewbDispatchVO.getEwbNo());
            map.put("operation_id",search.get("operationId"));
            List<HsEwbsDispatcherSub> subs = ewbsDispatcherSubService.selectByMap(map);
            ewbDispatchVO.setDispatcherSubList(subs);
        }
        return ewbDispatchVOS;
    }

    /**
     * 新增派件入口
     *
     * @param dispatchAddDTO
     * @return
     */
    public Map<String, String> addDispatch(DispatchAddDTO dispatchAddDTO) {
        Map<String, String> m = new HashMap<>();
        List<HsEwbsDispatchDetail> list = dispatchAddDTO.getDetails();
        if (list == null || list.isEmpty()) {
            return null;
        }
        String operationId = dispatchAddDTO.getOperationId();
        Integer siteId = dispatchAddDTO.getSiteId();
        Integer createdBy = LoginDetailUtils.getCurrentEmployeeId();//当前操作人

        Integer totalPiece = 0;
        BigDecimal totalWeight = new BigDecimal(0);
        BigDecimal totalVol = new BigDecimal(0);

        for (HsEwbsDispatchDetail detail : list) {
            totalPiece = totalPiece + detail.getPiece();
            totalWeight = totalWeight.add(detail.getWeight());
            totalVol = totalVol.add(detail.getVol());
        }
        HsEwbsDispatch dispatch = new HsEwbsDispatch();
        if(StringUtils.isEmpty(dispatchAddDTO.getOperationId())){

            operationId = String.valueOf(SnowflakeIdFactory.getNextId());
            dispatchAddDTO.setOperationId(operationId);
            dispatchAddDTO.setSiteId(siteId);
            dispatchAddDTO.setCreatedBy(createdBy);
            dispatchAddDTO.setCreatedTime(DateUtils.getNowDate());
            dispatchAddDTO.setRdStatus(1);
            dispatchAddDTO.setPiece(totalPiece);
            dispatchAddDTO.setWeight(totalWeight);
            dispatchAddDTO.setVol(totalVol);
            dispatchAddDTO.setSourceType(dispatchAddDTO.getSourceType());
            dispatchAddDTO.setDispatchTime(dispatchAddDTO.getDispatchTime());
            BeanUtils.copyProperties(dispatchAddDTO, dispatch);
            baseMapper.insert(dispatch);
        }else {

            dispatchAddDTO.setModifiedTime(DateUtils.getCurrentDate());
            dispatchAddDTO.setModifiedBy(createdBy);
            BeanUtils.copyProperties(dispatchAddDTO, dispatch);
            baseMapper.updateById(dispatch);

            //还原子单库存为在库
            Map<String, Object> search = new HashMap<>();
            Map updateInfo = new HashMap();
            search.put("operationId",operationId);
            List<EwbDispatchVO> dispatchVOS = baseMapper.getEwbInfoByDispatchNo(search);
            for(EwbDispatchVO ewbDispatchVO : dispatchVOS) {
                updateInfo.put("siteId",siteId);
                updateInfo.put("ewb_no",ewbDispatchVO.getEwbNo());
                updateInfo.put("status",OperationType.STOCK_ON);
                List<HsEwbSubStock> stocks = stockService.getStockListBySiteId(login.getLoginSiteId(),
                        ewbDispatchVO.getEwbNo(), OperationType.STOCK_DISPATCH_ON_THE_WAY);
                if (stocks.size() < ewbDispatchVO.getPiece()) {
                    throw new BaseExcept(NOT_ENOUGH_STOCK);
                }
                List<HsEwbSubStock> subs ;
                if (stocks.size() == ewbDispatchVO.getPiece()) {
                    subs = stocks;
                } else {
                    subs = new ArrayList<>();
                    for (int i = 0; i < ewbDispatchVO.getPiece(); i++) {
                        subs.add(stocks.get(i));
                    }
                }
                updateInfo.put("subs", subs);
                stockService.updateBatch(updateInfo);
            }

            //派送详情数据
            Wrapper<HsEwbsDispatchDetail> dispatchDetailWrapper = new EntityWrapper<>();
            dispatchDetailWrapper.where("operation_id ={0}", operationId);
            dispatchDetailService.delete(dispatchDetailWrapper);

            //删除快件跟踪记录
            Wrapper<HsOptQuery> optQueryWrapper = new EntityWrapper<>();
            optQueryWrapper.where("operation_id ={0}", operationId);
            queryService.delete(optQueryWrapper);

            //删除派送库存数据
            Wrapper<HsEwbsDispatcherSub> dispatchSubWrapper = new EntityWrapper<>();
            dispatchSubWrapper.where("operation_id ={0}", operationId);
            ewbsDispatcherSubService.delete(dispatchSubWrapper);

        }
        List<HsOptQuery> queryList = new ArrayList<>();
        List<HsEwbsDispatchDetail> dispatchDetails = new ArrayList<>();
        for (HsEwbsDispatchDetail detail : list) {
            //运单详情表
            detail.setOperationId(operationId);
            detail.setRdStatus(1);
            dispatchDetails.add(detail);

            //库存进行调整
            List<HsEwbSubStock> stockList = stockService.getStockListBySiteId(siteId,
                    detail.getEwbNo(), OperationType.STOCK_ON);
            if (stockList == null || stockList.size() < detail.getPiece()) {
                throw new BaseExcept(DISPATCH_STOCK_NOT_ENOUGH_ERR);
            }
            StockPdaInfoBean stockPdaInfoBean = new StockPdaInfoBean();
            stockPdaInfoBean.setEwbNo(detail.getEwbNo());
            List<String> subEwbs = new ArrayList<>();
            for (HsEwbSubStock aStockList : stockList) {
                subEwbs.add(aStockList.getSubEwb());
            }
            stockPdaInfoBean.setSubEwbs(subEwbs);
            stockPdaInfoBean.setSiteId(siteId);
            stockPdaInfoBean.setNextSiteId(0);//为派送,无下一站

            stockPdaInfoBean.setSize(detail.getPiece());
            stockService.dispatchEwbByPda(stockPdaInfoBean);

            //运单跟踪信息
            HsOptQuery query = new HsOptQuery();
            query.setEwbNo(detail.getEwbNo());
            query.setStep(OperationType.DISPATCHING);
            query.setOperationId(String.valueOf(SnowflakeIdFactory.getNextId()));
            query.setOperationTime(DateUtils.getNowDate());
            query.setOperator(createdBy);
            query.setOperationSiteId(siteId);
            queryList.add(query);

            //插入配载单和子单关联
            List<HsEwbsDispatcherSub> ewbSubStockList = new ArrayList<>();
            try {
                if (CollectionUtils.isNotEmpty(detail.getSubs())) {
                    for (HsEwbsDispatcherSub dispatcherSub : detail.getSubs()) {
                        HsEwbsDispatcherSub ewbsStowageSub = new HsEwbsDispatcherSub();
                        ewbsStowageSub.setEwbNo(detail.getEwbNo());
                        ewbsStowageSub.setOperationId(operationId);
                        ewbsStowageSub.setCreatedTime(DateUtils.getCurrentDate());
                        ewbsStowageSub.setSiteId(siteId);
                        ewbsStowageSub.setSubEwb(dispatcherSub.getSubEwb());
                        ewbSubStockList.add(ewbsStowageSub);
                    }
                    ewbsDispatcherSubService.insertBatch(ewbSubStockList);
                }
            } catch (Exception e) {
                String exception = e.getCause().getMessage();
                if (exception.toLowerCase().contains("duplicate entry")) {
                    throw new BaseExcept(ResponseStatus.DISPATCH_ADD_ERR);
                }
            }
        }

        dispatchDetailService.insertBatch(dispatchDetails);
        queryService.insertBatch(queryList);
        m.put("code", "200");
        m.put("message", "成功");
        m.put("subEwb", "");
        return m;
    }

    /**
     * BS端派件接口
     *
     * @param dispatchAddDTO
     * @return
     * @throws BaseExcept
     */
    @Override
    public Map<String, String> addDispatchBS(DispatchAddDTO dispatchAddDTO) throws BaseExcept {
        dispatchAddDTO.setDeviceCode("BS");
        if (dispatchAddDTO.getSourceType()!=null && dispatchAddDTO.getSourceType()==2){
            List<HsEwbsDispatchDetail> dispatchDetails = dispatchAddDTO.getDetails();
            for (HsEwbsDispatchDetail dispatchDetail : dispatchDetails) {
                for (HsEwbsDispatcherSub dispatcherSub : dispatchDetail.getSubs()) {
                    Map search = new HashMap();
                    search.put("sub_ewb", dispatcherSub.getSubEwb());
                    List<HsEwbsDispatcherSub> dispatcherSubs = ewbsDispatcherSubService.selectByMap(search);
                    if (!dispatcherSubs.isEmpty()){
                        Map<String, String> map = new HashMap<>();
                        map.put("code", "500");
                        map.put("message", "数据重复");
                        map.put("subEwb", dispatcherSub.getSubEwb());
                        return map;
                    }
                }
                HsEwbSub hsEwbSub = hsEwbSubService.selectEwbNo(dispatchDetail.getSubs().get(0).getSubEwb());
                BigDecimal size = new BigDecimal(dispatchDetail.getSubs().size());
                dispatchDetail.setPiece(dispatchDetail.getSubs().size());
                dispatchDetail.setWeight(hsEwbSub.getWeight().multiply(size));
                dispatchDetail.setVol(hsEwbSub.getVol().multiply(size));
            }
        }
        return addDispatch(dispatchAddDTO);
    }


    /**
     * 删除派送单
     *
     * @param operationId
     * @return
     * @throws BaseExcept
     */
    @Override
    public int deleteDispatchByEwbNo(String operationId) throws BaseExcept {
        Map params = new HashMap();
        params.put("operationId", operationId);
        List<HsEwbsDispatchDetail> details = dispatchDetailService.queryEwbDispatchDetail(params);
        //删除派送单详情
        Wrapper<HsEwbsDispatchDetail> wrapper = new EntityWrapper<>();
        wrapper.where("operation_Id={0}", operationId);
        HsEwbsDispatchDetail dispatchDetail = new HsEwbsDispatchDetail();
        dispatchDetail.setRdStatus(0);
        //dispatchDetail.setOperationId(operationId);
        dispatchDetailService.update(dispatchDetail, wrapper);
        //调整托运单库存数据
        for (HsEwbsDispatchDetail detail : details) {
//            detail.setSiteId(1);
            //detail.setSiteId(login.getLoginSiteId());
            dispatcherStockRollBack(detail);
        }
        //删除派送单
        HsEwbsDispatch dispatch = new HsEwbsDispatch();
        dispatch.setOperationId(operationId);
        dispatch.setModifiedBy(login.getLoginUserId());
        dispatch.setModifiedTime(DateUtils.getNowDate());
        dispatch.setRdStatus(0);
        return baseMapper.updateById(dispatch);
    }


    @Override
    public List<DispatchVO> exportDispatchQueryList(Map map) throws BaseExcept {
        return baseMapper.exportDispatchQueryList(map);
    }

    /**
     * 获取派送单路由
     *
     * @param map
     * @return
     * @throws BaseExcept
     */
    @Override
    public List<DispatchRouteVO> queryDispatchRouteList(Map map) throws BaseExcept {
        return baseMapper.queryDispatchRouteList(map);
    }


    /**
     * 运单库存调整
     */
    public void dispatcherStockRollBack(HsEwbsDispatchDetail detail) {
        /**------------------库存回退开始-----------------------**/
        Map updateInfo = new HashMap();
        updateInfo.put("siteId", login.getLoginSiteId());
        updateInfo.put("ewbNo", detail.getEwbNo());
        updateInfo.put("status", OperationType.STOCK_ON);
        List<HsEwbSubStock> stocks = stockService.getStockListBySiteId(login.getLoginSiteId(),
                detail.getEwbNo(), OperationType.STOCK_DISPATCH_ON_THE_WAY);
        if (stocks.size() < detail.getPiece()) {
            throw new BaseExcept(NOT_ENOUGH_STOCK);
        }
        List<HsEwbSubStock> subs ;
        if (stocks.size() == detail.getPiece()) {
            subs = stocks;
        } else {
            subs = new ArrayList<>();
            for (int i = 0; i < detail.getPiece(); i++) {
                subs.add(stocks.get(i));
            }
        }
        updateInfo.put("subs", subs);
        stockService.updateBatch(updateInfo);
        /**------------------库存回退结束-----------------------**/
    }

    @Override
    public List<DispatchVO> queryArrivalNoList(Map map) throws BaseExcept {
        return baseMapper.queryDispatchEwbList(map);
    }
}
